package com.xyb.config.result;

import com.xyb.entity.Result;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class GlobalResult implements InitializingBean {
    //请求映射处理器适配器
    @Resource
    private RequestMappingHandlerAdapter adapter;

    /**
     * 初始化容器时执行
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        //根据此适配器获取 处理方法返回值的处理器列表
        List<HandlerMethodReturnValueHandler> unmodifiableList = adapter.getReturnValueHandlers();

        List<HandlerMethodReturnValueHandler> list = new ArrayList<>(unmodifiableList.size());

        for (HandlerMethodReturnValueHandler i : unmodifiableList) {
            if (i instanceof RequestResponseBodyMethodProcessor) {
                list.add(new GlobalResultHandler(i));
            } else {
                list.add(i);
            }
        }
        //重新设置适配器 方法返回值处理列表
        adapter.setReturnValueHandlers(list);
    }

    private class GlobalResultHandler implements HandlerMethodReturnValueHandler{
        private HandlerMethodReturnValueHandler r;

        public GlobalResultHandler(HandlerMethodReturnValueHandler r) {
            this.r = r;
        }

        @Override
        public boolean supportsReturnType(MethodParameter returnType) {
            return r.supportsReturnType(returnType);
        }

        /**
         *
         * @param o             返回数据对象【就是Controller层中，处理器[请求接口]的返回值】
         * @param returnType    处理器的方法参数
         * @param mavContainer
         * @param webRequest
         * @throws Exception
         */
        @Override
        public void handleReturnValue(Object o, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
            if(o instanceof Result){
                r.handleReturnValue(o,returnType,mavContainer,webRequest);
                return;
            }
            Result<Object> result = new Result<>();
            result.setData(o);
            r.handleReturnValue(result,returnType,mavContainer,webRequest);
        }
    }
}
